package cn.yangliu.nacos.comm.tools;

import java.util.Map;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * The type of nacos.
 *
 * @author 问道于盲
 * @date 2019 -12-31
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {

    /**
     * current class's static member
     * The constant INSTANCE.
     */
    private static final SpringContextUtils INSTANCE = new SpringContextUtils();

    /**
     * current class instance's member.
     * The Application context.
     */
    private ApplicationContext applicationContext;

    /**
     * current class method for setter.
     * Sets application context.
     *
     * @param applicationContext the application context
     */
    @Override
    public final void setApplicationContext(ApplicationContext applicationContext) {
        if (INSTANCE.applicationContext == null) {
            INSTANCE.applicationContext = applicationContext;
        }
    }

    /**
     * get Application Context
     *
     * @return application context
     */
    public static ApplicationContext getApplicationContext() {
        return INSTANCE.applicationContext;
    }

    /**
     * current class method for getter.
     * Gets bean of type.
     *
     * @param <T>   the type parameter
     * @param clazz the clazz
     * @return the bean of type
     */
    public static <T> Map<String, T> getBeanOfType(Class<T> clazz) {
        return getApplicationContext().getBeansOfType(clazz);
    }

    /**
     * current class method for getter.
     * Gets bean.
     *
     * @param name the name
     * @return the bean
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * current class method for getter.
     * Gets bean.
     *
     * @param <T>   the type parameter
     * @param clazz the clazz
     * @return the bean
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * current class method for getter.
     * Gets bean.
     *
     * @param <T>   the type parameter
     * @param name  the name
     * @param clazz the clazz
     * @return the bean
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}
